﻿using BPMN.Domain;
using Microsoft.Data.SqlClient.DataClassification;
using System.Linq;
using System.Reflection;
using BPMN.DomianShare;
namespace BPMN.WebApi
{
    public static class InjectHelper
    {
        public static IServiceCollection AddDataService(this IServiceCollection services)
        {
            //typeof:获取类型
            var singletonType = typeof(ISingleton); // 单例
            var transientType = typeof(ITransient); // 瞬时
            var scopedType = typeof(IScoped); // 作用域

            //AppDomain:应用程序域
            //CurrentDomain:当前域
            // AppDomain.CurrentDomain.GetAssemblies():这个方法获取的是当前应用程序域已经加载的，未加载的是获取不到的(尽管引用了该项目),所以在配置依赖注入时，可能会出现有些程序集拿不到的情况，导致没有注入所有需要的服务程序集
            var aa = AppDomain.CurrentDomain.GetAssemblies();

            //获取该应用所有引用的程序集
            var bb = Assembly.GetEntryAssembly().GetReferencedAssemblies().Select(Assembly.Load);
            //获取实现了三个生命周期接口的程序集
            var allTypes = bb
                .SelectMany(x => x.GetTypes().Where(x => x.GetInterfaces().Contains(transientType) || x.GetInterfaces().Contains(singletonType) || x.GetInterfaces().Contains(scopedType)));

            //class的程序集
            var ImpClass = allTypes.Where(x => x.IsClass).ToArray();
            //接口程序集
            var ImpInterface = allTypes.Where(x => x.IsInterface).ToArray();

            foreach (var impClass in ImpClass)
            {
                var interfaceType = ImpInterface.FirstOrDefault(x => x.IsAssignableFrom(impClass));
                //class有接口，用接口注入
                if (interfaceType != null)
                {
                    // 判断用什么方式注入
                    //var aaa = interfaceType.GetInterfaces();
                    if (interfaceType.GetInterfaces().Contains(singletonType))
                    {
                        //单例
                        services.AddSingleton(interfaceType, impClass);
                    }
                    else if (interfaceType.GetInterfaces().Contains(transientType))
                    {
                        //瞬时
                        services.AddTransient(interfaceType, impClass);
                    }
                    else if (interfaceType.GetInterfaces().Contains(scopedType))
                    {
                        //作用域
                        services.AddScoped(interfaceType, impClass);
                    }

                }
                else//没有接口的情况
                {
                    // 判断用什么方式注入
                    if (interfaceType.GetInterfaces().Contains(singletonType))
                    {
                        //单例
                        services.AddSingleton(impClass);
                    }
                    else if (interfaceType.GetInterfaces().Contains(transientType))
                    {
                        //瞬时
                        services.AddTransient(impClass);
                    }
                    else if (interfaceType.GetInterfaces().Contains(scopedType))
                    {
                        //作用域
                        services.AddScoped(impClass);
                    }

                }

            }
            return services;
        }
    }
}
